/**
 * Copyright (c) 2016-2019 九点科技 All rights reserved.
 *
 * http://www.9dyun.cn
 *
 * 版权所有，侵权必究！
 */
package com.dian.modules.inv.service.impl;

import cn.hutool.core.util.StrUtil;
import com.dian.common.utils.*;
import com.dian.common.validator.ValidatorUtils;
import com.dian.common.validator.group.AddGroup;
import com.dian.common.validator.group.UpdateGroup;
import com.dian.modules.enums.inv.*;
import com.dian.modules.inv.entity.*;
import com.dian.modules.inv.service.*;
import com.dian.modules.inv.poi.vo.TranHeadExportVO;
import com.dian.modules.inv.poi.vo.TranLineExportVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dian.common.exception.RRException;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.collections.CollectionUtils;
import com.dian.common.server.CommonService;
import com.dian.modules.inv.dao.TranHeadDao;
import com.dian.modules.inv.service.TranLineService;

/**
 * 调拨单服务实现类
 *
 * @author xiaolai
 * @email xiaolai@9dyun.cn
 * @date 2019-06-11 00:17:00
 */
@Service("tranHeadService")
public class TranHeadServiceImpl extends ServiceImpl<TranHeadDao, TranHeadEntity> implements TranHeadService {


    @Autowired
    public CommonService commonService;

    @Autowired
    public TranLineService tranLineService;

    @Autowired
    public InHeadService inHeadService;

    @Autowired
    public OutHeadService outHeadService;



    /**
     * 调拨单分页
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        IPage<TranHeadEntity> page = this.page(new Query<TranHeadEntity>().getPage(params),getQueryWrapper(params) );
        return new PageUtils(page);
    }

    /**
    *  调拨单新增
    * @param tranHeadEntity
    * @return
    */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean saveInfo(TranHeadEntity tranHeadEntity) {
        //设置月份
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        String tranMonth = format.format(new Date());
        tranHeadEntity.setTranMonth(tranMonth);
       /* SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        String inMonth = format.format(new Date());
        inHeadEntity.setInMonth(inMonth);
        //设置调拨单编码*/
        tranHeadEntity.setTranNo(commonService.getCode(TranHeadEntity.class));

        //数据完整性校验
        this.paramsCheck(tranHeadEntity,AddGroup.class);

        //设置编码，基础默然初始化数据设置
        //tranHeadEntity.setOrderNo(commonService.getOrderCode("XSD"));
        //tranHeadEntity.setOrderDate(new Date());


        //保存主表
        this.save(tranHeadEntity);

        //保存从表
        if (CollectionUtils.isNotEmpty(tranHeadEntity.getTranLineEntityList())) {
            List<TranLineEntity> detailList = tranHeadEntity.getTranLineEntityList();
            for (TranLineEntity detail : detailList) {
                detail.setTranId(tranHeadEntity.getId());
            }
            tranLineService.saveBatch(tranHeadEntity.getTranLineEntityList());
        }
        return true;
    }

    /**
     *调拨单更新
     * @param tranHeadEntity
     * @return
     */
    @Override
    public boolean updateInfo(TranHeadEntity tranHeadEntity) {

        //修改状态校验
        this.updateCheck(tranHeadEntity.getId());

        //主表数据完整性校验
        this.paramsCheck(tranHeadEntity, UpdateGroup.class);

        //更新主表
        this.updateById(tranHeadEntity);

        //更新从表
        tranLineService.updateInfo(tranHeadEntity);

        return true;
    }

    /**
     *调拨单删除
     * @param id
     * @return
     */
    @Override
    public boolean deleteInfo(Long id) {

        //删除状态校验
        this.deleteCheck(id);

        //更新从表
        tranLineService.deleteInfo(id);

        //更新主表
        this.remove(new QueryWrapper<TranHeadEntity>().eq("id",id));

        return true;
    }

    /**
     * 调拨单详情
     * @param id
     * @return
     */
    @Override
    public TranHeadEntity getInfo(Long id) {
        TranHeadEntity tranHeadEntity =getById(id);
        List<TranLineEntity> lineList=tranLineService.queryList(id);
        tranHeadEntity.setTranLineEntityList(lineList);
        return tranHeadEntity;
    }

    /**
     * 调拨单审核
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean checkInfo(Long id) {

        TranHeadEntity tranHeadEntity =this.getById(id);

        TranHeadEntity info = this.getInfo(id);

        tranHeadEntity.setTranLineEntityList(info.getTranLineEntityList());

        checkCheck(tranHeadEntity);

        InHeadEntity inHeadEntity = inHead(tranHeadEntity);
        OutHeadEntity outHeadEntity = outHead(tranHeadEntity);

        inHeadService.createInHead(inHeadEntity);
        outHeadService.createOutHead(outHeadEntity);

        tranHeadEntity.setTranState(TranHead_TranStateEnum.AUDITED.getValue());
        tranHeadEntity.setCheckDate(new Date());
        tranHeadEntity.setCheckUserId(commonService.getUserId());
        tranHeadEntity.setCheckUserName(commonService.getUserName());

        //saleOrderHeadEntity.setOrderState(OrderHead_OrderStateEnum.AUDITED.getValue());
        //saleOrderHeadEntity.setOrderDate(new Date());
        ///saleOrderHeadEntity.setCheckUserId(commonService.getUserId());
        //saleOrderHeadEntity.setCheckUserName(commonService.getUserName());
        return this.updateById(tranHeadEntity);
    }

    /**
     * 调拨单分页导出
     * @param params
     * @return
     */
    @Override
    public List<TranHeadExportVO> exportList(Map<String, Object> params) {
        List<TranHeadEntity> list  = new ArrayList<>();
        if(!StrUtil.isBlankIfStr(params.get("exprotType"))){
            //导出当前页
            list= this.page(new Query<TranHeadEntity>().getPage(params),getQueryWrapper(params)).getRecords();
        }else{
            //导出全部
            list= this.list(getQueryWrapper(params));
        }
        List<TranHeadExportVO> resultList = BeanConverter.convertList(list, TranHeadExportVO.class);
        // 封装明细
        if(CollectionUtils.isNotEmpty(resultList)){
            for(TranHeadExportVO tranHeadEntity : resultList){
                List<TranLineEntity>  tranLineEntityList = tranLineService.queryList(tranHeadEntity.getId());
                tranHeadEntity.setTranHeadExportVOList(BeanConverter.convertList( tranLineEntityList,TranLineExportVO.class));
            }
        }
        return resultList;
    }





    /***********************************************************************************************/
    /****************************************** 私有方法 ********************************************/
    /***********************************************************************************************/

    /**
     * 修改状态校验
     *
     * @param
     */
    private void updateCheck(Long id) {
        TranHeadEntity tranHeadEntity =this.getById(id);

        if (tranHeadEntity.getTranState().equals(TranHead_TranStateEnum.AUDITED.getValue())){
            throw new RRException(String.format("已审核的调拨单禁止修改"));
        }
        //if(tranHeadEntity.getOrderState().equals(OrderHead_OrderStateEnum.AUDITED.getValue())){
        //    throw new RRException(String.format("已审核的销售订单禁止修改"));
        //}
    }
    /**
     * 审核状态校验
     *
     * @param
     */
    private void checkCheck(TranHeadEntity tranHeadEntity) {
        if (!tranHeadEntity.getTranState().equals(TranHead_TranStateEnum.WAITCHECK.getValue())){
            throw new RRException(String.format("[%s]已审核",tranHeadEntity.getTranNo()));
        }

        //if(tranHeadEntity.getOrderState().equals(OrderHead_OrderStateEnum.AUDITED.getValue())){
        //    throw new RRException(String.format("[%s] 此销售单已审核"),);
        //

    }

    /**
     * 删除状态校验
     *
     * @param
     */
    private void deleteCheck(Long id) {
        TranHeadEntity tranHeadEntity =this.getById(id);
        if(!tranHeadEntity.getTranState().equals(TranHead_TranStateEnum.WAITCHECK.getValue())){
            throw new RRException(String.format("只允许删除未审核的销售订单",tranHeadEntity.getTranNo()));
        }
        //if(!saleOrderHeadEntity.getOrderState().equals(OrderHead_OrderStateEnum.WAITCHECK.getValue())){
        //        //    throw new RRException(String.format("只允许删除未审核的销售订单"));
        //}
    }

    /**
     * 新增和修改参数校验
     *
     * @param record
     */
    private void paramsCheck(TranHeadEntity record, Class<?> cls) {

        ValidatorUtils.validateEntity(record, cls);

        if (CollectionUtils.isEmpty(record.getTranLineEntityList())) {
            throw new RRException("调拨单明细数据不能为空");
        }
        ListUtils.setPropertyValue(record.getTranLineEntityList(),"warehouseId",record.getToWarehouseId());
        ListUtils.setPropertyValue(record.getTranLineEntityList(),"warehouseCode",record.getToWarehouseCode());
        ListUtils.setPropertyValue(record.getTranLineEntityList(),"warehouseName",record.getToWarehouseName());
        ListUtils.setPropertyValue(record.getTranLineEntityList(),"warehouseId",record.getFromWarehouseId());
        ListUtils.setPropertyValue(record.getTranLineEntityList(),"warehouseId",record.getFromWarehouseCode());
        ListUtils.setPropertyValue(record.getTranLineEntityList(),"warehouseId",record.getToWarehouseName());

        ListUtils.setPropertyValue(record.getTranLineEntityList(),"inMonth",record.getTranMonth());
        ListUtils.setPropertyValue(record.getTranLineEntityList(),"inState",record.getTranState());
        for (TranLineEntity tranLineEntity : record.getTranLineEntityList()) {
            int index = record.getTranLineEntityList().indexOf(tranLineEntity) + 1;

        if(tranLineEntity.getBaseNum() == null){
            throw new RRException(String.format("参数错误，商品明细第%s行中[商品数量]不能为空", index));
        }

        if(tranLineEntity.getQtyNum() == null){
            throw new RRException(String.format("参数错误，商品明细第%s行中[商品数量]不能为空", index));
        }

        if(tranLineEntity.getAuxNum() == null){
            throw new RRException(String.format("参数错误，商品明细第%s行中[商品数量]不能为空", index));
        }

        if(tranLineEntity.getGoodsDiscount() == null){
            throw new RRException(String.format("参数错误，商品明细第%s行中[商品折扣]不能为空", index));
        }

            /*
            if (tranLineEntity.getGoodsId() == null) {
                throw new RRException(String.format("参数错误，商品明细第%s行中[商品ID]不能为空", index));
            }

            if (tranLineEntity.getGoodsCode() == null) {
                throw new RRException(String.format("参数错误，商品明细第%s行中[商品编码]不能为空", index));
            }
            if (tranLineEntity.getGoodsName() == null) {
                throw new RRException(Strin                                         g.format("参数错误，商品明细第%s行中[商品编码]不能为空", index));
            }
            if (tranLineEntity.getGoodsNum() == null) {
                throw new RRException(String.format("参数错误，商品明细第%s行中[商品数量]不能为空", index));
            }
            */
        }
    }

    /**
     * 获取查询条件
     *
     * @param
     */
    private QueryWrapper<TranHeadEntity> getQueryWrapper(Map<String, Object> params) {
        QueryWrapper<TranHeadEntity> queryWrapper=new QueryWrapper<>();
        if(!StrUtil.isBlankIfStr(params.get("tranDate"))){
            String tranDate=String.valueOf(params.get("tranDate"));
            String[] tranDateRange=tranDate.split("至");
            if(tranDateRange.length==2){
                queryWrapper.gt("tran_date", DateUtils.getBeginTimeOfDate(tranDateRange[0]));
                queryWrapper.lt("tran_date",DateUtils.getBeginTimeOfDate(tranDateRange[1]));
            }else{
                queryWrapper.gt("tran_date",DateUtils.getBeginTimeOfDate(tranDate));
            }
        }

        if(!StrUtil.isBlankIfStr(params.get("tranNo"))){
            queryWrapper.likeLeft("tran_No",params.get("tranNo"));
        }
      /*  if(!StrUtil.isBlankIfStr(params.get("tranState"))){
            queryWrapper.likeLeft("tran_state",params.get("tranState"));
        }*/
        queryWrapper.orderByAsc("id");
        return queryWrapper;
    }

    private InHeadEntity inHead (TranHeadEntity ranHeadEntity) {
        //入库主对象
        InHeadEntity inHeadEntity = new InHeadEntity();
        //单号
        inHeadEntity.setInNo(ranHeadEntity.getTranNo());
        //入库时间
        inHeadEntity.setInDate(ranHeadEntity.getTranDate());
        //入库月份
        inHeadEntity.setInMonth(ranHeadEntity.getTranMonth());
        //仓库id
        inHeadEntity.setWarehouseId(ranHeadEntity.getToWarehouseId());
        //仓库编码
        inHeadEntity.setWarehouseCode(ranHeadEntity.getToWarehouseCode());
        //仓库名称
        inHeadEntity.setWarehouseName(ranHeadEntity.getToWarehouseName());
        //入库类型
        inHeadEntity.setInType(InHead_InTypeEnum.TRAN.getValue());
        //单据状态
        inHeadEntity.setInState(InHead_InStateEnum.WAITCHECK.getValue());
        inHeadEntity.setInLineEntityList(BeanConverter.convertList(ranHeadEntity.getTranLineEntityList(), InLineEntity.class));
        return  inHeadEntity;
    }

    private OutHeadEntity outHead (TranHeadEntity ranHeadEntity){
        //出库主对象
        OutHeadEntity outHeadEntity = new OutHeadEntity();
        //单号
        outHeadEntity.setOutNo(ranHeadEntity.getTranNo());
        //出库事件
        outHeadEntity.setOutDate(ranHeadEntity.getTranDate());
        //出库月份
        outHeadEntity.setOutMonth(ranHeadEntity.getTranMonth());
        //仓库id
        outHeadEntity.setWarehouseId(ranHeadEntity.getToWarehouseId());
        //仓库编码
        outHeadEntity.setWarehouseCode(ranHeadEntity.getFromWarehouseCode());
        //仓库名称
        outHeadEntity.setWarehouseName(ranHeadEntity.getFromWarehouseName());
        //出库类型
        outHeadEntity.setOutType(OutHead_OutTypeEnum.NORMAL.getValue());
        //单据状态
        outHeadEntity.setOutState(OutHead_OutStateEnum.WAITCHECK.getValue());
        outHeadEntity.setOutLineEntityList(BeanConverter.convertList(ranHeadEntity.getTranLineEntityList(),OutLineEntity.class));
        return outHeadEntity;
    }




}
